#ifndef PHYSICS_H
#define PHYSICS_H

//Simple includes
#include "pForward.h"
#include <map>
#include <string>
#define	MAX_ENTITIES 4096


class b2World;

namespace Tmpl8
{

class vector3;

	struct JointProperties
	{
		JointProperties()
		{
			lowertranslation = uppertranslation = motorforce = motorspeed = 
				length = frequency = dampingratio = maxMotorTorque = lowerAngle = upperAngle = 0.0f;
			enablelimit = false;
			enablemotor = false;
			collideconnected = true;
			strcpy(body1, "No Name");
			strcpy(body2, "No Name");
			strcpy(type, "No Name");
		}
		char type[255];
		char body1[255];
		vector3* anchorpoint1;
		char body2[255];
		vector3* anchorpoint2;
		float length;
		float frequency;
		float dampingratio;
		float lowertranslation;
		float uppertranslation;
		bool enablelimit;
		float motorforce;
		float motorspeed;
		bool enablemotor;
		float maxMotorTorque;
		float lowerAngle;
		float upperAngle;
		bool collideconnected;
	};



class Player;
class LineProp;
class MapData;
class pWeb;
class Physics
{
public:
							Physics();
							~Physics(){}

	//Class functions
	void					Tick();
	void					Render();
	void					CleanUp(){}

	//Factory functions:
	pBody*					CreateBody(vector3 aPos, float aAngle, PHYSICS_MODE aMode);
	pPlayer*				CreatePlayer(vector3 aPos);
	
	pJoint*					CreateJoint(JointProperties* aJointProperties);
	pTrigger*				CreateTrigger(vector3 aPos, float aAngle, PHYSICS_MODE aMode);
	pRay*					CreateRay(float length){return 0;}
	pChain*					CreateChain(ChainProperties* aChainProperties);
	void					DestroyEntity(pEntity* aEntity){}

	//Misc functions:
	vector3*				GetOffset()													{return mCamOffset;}
	void					SetPointerToCam(vector3* aPointerToCam);
	void					LoadMapData(MapData *aMapData);
	pTrigger*				AddNextMapTrigger(char* NextMap, AABox* exitbox, Map* aMap);
	pTrigger*				AddNextMapTrigger(LevelTriggerProperties* aLevelTriggerProperties, Map* aMap);
	pTrigger*				AddWaterBox(vector3 aPos, vector3 aSize, float aAngle);
	pTrigger*				AddDamageTrigger(vector3 aPos, vector3 aSize, float aAngle, char* aMaterial,  PHYSICS_MODE aMode);
	pPlayer*				GetPlayer();
	pMaterial*				GetMaterial(std::string aName);
	pBody*					GetBodyByName(std::string aName);

	//Box2D functions
	b2World*				GetWorld() { return mWorld; }
	void					SetWorld(b2World* val) { mWorld = val; }

	static Physics*			mInstance;
private:
	void					InitWorld();
	void					InitPlayer();
	void					InitMaterials();
	void					DeleteMaterials(){;}

	pWeb*					CreateWeb();

	//Container variables
	pEntity*				mEntities[MAX_ENTITIES];	//List of entities;
	unsigned int			mEntityIdx;
	std::map<std::string, pMaterial*>  mMaterials;
	pCollisionHandler*		mCollisionHandler;

	//Misc variables
	vector3*				mCamOffset;
	pPlayer*				mPlayer;
	pWeb*					mWeb;

	//2dBox Specific
	b2World* mWorld;


	
};


}; //Namespace tmpl.

#endif